分类
联系方式
  1. 新浪微博
  2. E-mail

DartVM Zone

介绍

Zone 是 Dart 中的一个语法概念。代码位于 sdk/lib/async/zone.dart。

该文件下的类结构:

Zone:
  • 抽象基类
  • 定义 Zone 的基础接口

_Zone:

  • 继承自 Zone,仍为抽象类
  • 引入 ZoneDelegate 代理模式

_CustomZone:

  • 非抽象
  • 用于自定义 Zone

_RootZone:

  • 非抽象
  • 用于根 Zone

Zone 类注解

Zone 表示一个环境,在该环境中,能够使异步调用保持稳定。

代码总是运行在 Zone 的上下文中,即 Zone.current。最初的 main 函数运行在默认的 Zone 即 Zone.root 中。

代码可以通过调用 runZoned 方法,运行在不同的 Zone 中。runZone 会创建一个新的 Zone。代码也可以调用 Zone.run,运行再一个已有的 Zone 中。

开发者可以通过创建一个新 Zone 来覆盖已有 Zone 的一些功能。比如,自定义 Zone 可以改变 print、timer、microtask 的行为,以及如何处理未捕获异常。

Zone 这个类不允许派生子类,用户可以通过对已有 Zone(Zone.current)进行 Fork 的方式,来创建自定义 Zone,并通过一个 ZoneSpecification 进行定制。

异步回调总是在它们被安排的 Zone 区域范围内运行。这通过两个步骤实现:

  1. 回调首先通过以下方法之一进行注册:registerCallback,registerUnaryCallback,registerBinaryCallback。这允许 Zone 记录一个回调的存在,并有可能修改它(通过返回一个不通的回调)。进行注册的代码(比如 Future.then)也会记住当前的 Zone,以便以后能够在该 Zone 运行回调。
  2. 注册的回调,之后会在记录的 Zone 上面执行,通过以下方法之一执行:run、runary、runBinary。

这些操作都由内部平台代码负责,开发者不用担心。可是,由底层系统或者通过原生扩展(native extension)提供的新的异步操作的开发这,必须遵守该协议,以实现 Zone 兼容。

为了简便,zone 还提供了 bindCallback 方法(一级对应的 bindUnaryCallback 和 bindBinaryCallback),让遵守 Zone 协议变得更加容易:这些方法首先调用对应的 register 方法,之后将返回回来的函数进行封装,使它能在当前 Zone 中调用。

与 Zone.runGuarded 对应的是,还提供了一组 bindCallbackGuarded、bindUnaryCallbackGuarded 和 bindBinaryCallbackGuarded。

Zone 抽象类

Zone 是一个抽象类,它的实现在哪里?在同一个文件的 _zone 类中实现了 Zone,但是 _zone 也是一个抽象类。

有两个静态属性:

  • Zone.root:返回根 Zone
  • Zone.current:返回当前 Zone

抽象方法:

  • fork:克隆当前 Zone,创建一个子 Zone
  • run:在 Zone 中执行一个 Action
  • runUnary:在 Zone 中执行一个 Action,该 Action 带有一个传参,与 run 不同指出在于有参数
  • runBinary:与前两者不通在于有两个传参,这里的 binary 不是二进制的意思,而是有两个参数的意思
  • registerCallback:
    • 在 Zone 中注册一个回调
    • 在使用回调实现基础的原始异步操作,用户必须调用 registerCallback 并传入一个注册回调
    • 这允许 Zone 可以记录其所需的各种信息,甚至可能也会对回调进行包装,这样,当回调后来在同一 Zone 运行的时候(使用 run),它就被准备好了。
    • 举例来说:Zone 可以选择是否存储回调在注册时的调用栈
    • 这个方法返回一个 ZoneCallback,这个跟注册回调的地方一起使用。通常来说返回的就是原始回调。
    • 自定义 Zone 可以拦截这个操作。默认的 Root Zone 只是进行透传。
  • bindCallback:也是注册一个回调,将它放在当前 Zone 中注册,一般用于其它 Zone 把回调放到根 Zone 中注册
  • scheduleMicrotask:
    • 在 Zone 中注册异步回调
    • 根 Zone 的实现与底层系统交互,会将回调作为 microtask 进行调度。
  • createTimer:在当前 Zone 创建一个单次定时器
  • createPeriodicTimer:在当前 Zone 创建一个循环定时器
  • print:日志打印函数,这个也是可以被 Hook 行为替换的


网络资源

Dart 文档